package com.rickpan.entity;

import jakarta.persistence.*;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

/**
 * 用户在线状态实体类
 * 为Socket.IO实时通讯准备
 */
@Entity
@Table(name = "user_online_status", 
       uniqueConstraints = @UniqueConstraint(columnNames = {"user_id"}))
@EntityListeners(AuditingEntityListener.class)
public class UserOnlineStatus {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "user_id", nullable = false, unique = true)
    private Long userId;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private Status status = Status.OFFLINE;

    @Column(name = "last_seen", nullable = false)
    private LocalDateTime lastSeen = LocalDateTime.now();

    @Column(name = "socket_id", length = 100)
    private String socketId;

    @Column(name = "device_info", length = 200)
    private String deviceInfo;

    @Column(name = "ip_address", length = 45)
    private String ipAddress;

    @LastModifiedDate
    @Column(name = "updated_at", nullable = false)
    private LocalDateTime updatedAt;

    // 关联关系
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", insertable = false, updatable = false)
    private User user;

    // 枚举定义
    public enum Status {
        ONLINE,     // 在线
        OFFLINE,    // 离线
        AWAY,       // 离开
        BUSY        // 忙碌
    }

    // 构造函数
    public UserOnlineStatus() {}

    public UserOnlineStatus(Long userId) {
        this.userId = userId;
        this.lastSeen = LocalDateTime.now();
    }

    public UserOnlineStatus(Long userId, Status status) {
        this.userId = userId;
        this.status = status;
        this.lastSeen = LocalDateTime.now();
    }

    // 业务方法
    public boolean isOnline() {
        return status == Status.ONLINE;
    }

    public boolean isOffline() {
        return status == Status.OFFLINE;
    }

    public void setOnline(String socketId, String deviceInfo, String ipAddress) {
        this.status = Status.ONLINE;
        this.socketId = socketId;
        this.deviceInfo = deviceInfo;
        this.ipAddress = ipAddress;
        this.lastSeen = LocalDateTime.now();
    }

    public void setOffline() {
        this.status = Status.OFFLINE;
        this.socketId = null;
        this.lastSeen = LocalDateTime.now();
    }

    public void updateLastSeen() {
        this.lastSeen = LocalDateTime.now();
    }

    public long getOfflineMinutes() {
        if (isOnline()) {
            return 0;
        }
        return java.time.Duration.between(lastSeen, LocalDateTime.now()).toMinutes();
    }

    // Getter和Setter方法
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
        this.lastSeen = LocalDateTime.now();
    }

    public LocalDateTime getLastSeen() {
        return lastSeen;
    }

    public void setLastSeen(LocalDateTime lastSeen) {
        this.lastSeen = lastSeen;
    }

    public String getSocketId() {
        return socketId;
    }

    public void setSocketId(String socketId) {
        this.socketId = socketId;
    }

    public String getDeviceInfo() {
        return deviceInfo;
    }

    public void setDeviceInfo(String deviceInfo) {
        this.deviceInfo = deviceInfo;
    }

    public String getIpAddress() {
        return ipAddress;
    }

    public void setIpAddress(String ipAddress) {
        this.ipAddress = ipAddress;
    }

    public LocalDateTime getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(LocalDateTime updatedAt) {
        this.updatedAt = updatedAt;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "UserOnlineStatus{" +
                "id=" + id +
                ", userId=" + userId +
                ", status=" + status +
                ", lastSeen=" + lastSeen +
                ", socketId='" + socketId + '\'' +
                ", deviceInfo='" + deviceInfo + '\'' +
                ", ipAddress='" + ipAddress + '\'' +
                ", updatedAt=" + updatedAt +
                '}';
    }
}
